﻿using Microsoft.AspNetCore.Http;
using SixLabors.Fonts;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Drawing.Processing;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;

namespace V6UEditor.Core.Handlers
{
    /// <summary>
    /// 上传处理器
    /// </summary>
    public class UploadHandler : Handler
    {
        public UploadConfig UploadConfig { get; private set; }
        public UploadResult Result { get; private set; }

        public UploadHandler(HttpContext context, UploadConfig config)
            : base(context)
        {
            this.UploadConfig = config;
            this.Result = new UploadResult() { State = UploadState.Unknown };
        }

        public override UEditorResult Process()
        {
            byte[] uploadFileBytes = null;
            string uploadFileName = null;

            if (UploadConfig.Base64)
            {
                uploadFileName = UploadConfig.Base64Filename;
                uploadFileBytes = Convert.FromBase64String(Request.Form[UploadConfig.UploadFieldName]);
            }
            else
            {
                var file = Request.Form.Files[UploadConfig.UploadFieldName];
                uploadFileName = file.FileName;

                if (!CheckFileType(uploadFileName))
                {
                    Result.State = UploadState.TypeNotAllow;
                    return WriteResult();
                }

                if (!CheckFileSize(file.Length))
                {
                    Result.State = UploadState.SizeLimitExceed;
                    return WriteResult();
                }

                uploadFileBytes = new byte[file.Length];
                try
                {
                    file.OpenReadStream().Read(uploadFileBytes, 0, (int)file.Length);
                }
                catch (Exception)
                {
                    Result.State = UploadState.NetworkError;
                    WriteResult();
                }
            }

            Result.OriginFileName = uploadFileName;

            string path_format = UploadConfig.PathFormat;
            if (!string.IsNullOrEmpty(UploadConfig.uploads_dir))
            {
                path_format = path_format.Replace("{uploads_dir}", UploadConfig.uploads_dir);
                path_format = path_format.Replace("//", "/");
            }

            // 确保路径使用正斜杠
            path_format = path_format.Replace('\\', '/');

            var save_path = PathFormatter.Format(uploadFileName, path_format);
            var localPath = Path.Combine(Config.WebRootPath, save_path);

            // 确保Linux路径正确
            localPath = localPath.Replace('\\', '/');

            UEditorResult result;
            try
            {
                var directoryPath = Path.GetDirectoryName(localPath);
                if (!Directory.Exists(directoryPath))
                {
                    Directory.CreateDirectory(directoryPath);
                }

                File.WriteAllBytes(localPath, uploadFileBytes);

                string[] water_exts = new string[] { ".jpg", ".jpeg", ".png" };
                if (water_exts.Contains(Path.GetExtension(uploadFileName).ToLower()))
                {
                    // 使用ImageSharp添加水印
                    using (var image = Image.Load(uploadFileBytes))
                    {
                        // 使用改进的字体获取方法
                        var font = GetAvailableFont();
                        var color = new SixLabors.ImageSharp.Color(new Rgba32(255, 255, 255, 128));
                        var position = new Point(image.Width - 220, image.Height - 50);

                        image.Mutate(x => x.DrawText(UploadConfig.water_mark, font, color, position));
                        image.Save(localPath);
                    }
                }

                Result.Url = save_path;
                Result.State = UploadState.Success;
            }
            catch (Exception ex)
            {
                Result.State = UploadState.FileAccessError;
                Result.ErrorMessage = ex.Message;
            }
            finally
            {
                result = WriteResult();
            }
            return result;
        }

        /// <summary>
        /// 获取系统可用字体并选择第一个可用的
        /// </summary>
        /// <param name="size"></param>
        /// <param name="style"></param>
        /// <returns></returns>
        private Font GetAvailableFont(float size = 20, FontStyle style = FontStyle.Bold)
        {
            // 按优先级排序的字体列表
            var preferredFonts = new[]
            {
                "WenQuanYi Zen Hei",    // 文泉驿正黑
                "Noto Sans CJK SC",      // 思源黑体
                "Microsoft YaHei",       // 微软雅黑(如果已安装)
                "SimHei",                // 黑体
                "DejaVu Sans",           // 英文字体
                "Liberation Sans",       // 英文字体
                SystemFonts.Families.First().Name  // 系统第一个可用字体
            };

            foreach (var fontName in preferredFonts)
            {
                if (SystemFonts.TryGet(fontName, out var fontFamily))
                {
                    return fontFamily.CreateFont(size, style);
                }
            }

            // 如果所有字体都不可用，使用默认字体
            return SystemFonts.Families.First().CreateFont(size, style);
        }

        private UEditorResult WriteResult()
        {
            return new UEditorResult
            {
                State = GetStateMessage(Result.State),
                Url = Result.Url,
                Title = Result.OriginFileName,
                Original = Result.OriginFileName,
                Error = Result.ErrorMessage
            };
        }

        private string GetStateMessage(UploadState state)
        {
            switch (state)
            {
                case UploadState.Success:
                    return "SUCCESS";
                case UploadState.FileAccessError:
                    return "文件访问出错，请检查写入权限";
                case UploadState.SizeLimitExceed:
                    return "文件大小超出服务器限制";
                case UploadState.TypeNotAllow:
                    return "不允许的文件格式";
                case UploadState.NetworkError:
                    return "网络错误";
                case UploadState.NotAuthenticated:
                    return "未通过身份验证";
            }
            return "未知错误";
        }

        private bool CheckFileType(string filename)
        {
            var fileExtension = Path.GetExtension(filename).ToLower();
            var result = UploadConfig.AllowExtensions.Select(x => x.ToLower()).Contains(fileExtension);
            return result;
        }

        private bool CheckFileSize(long size)
        {
            return size < UploadConfig.SizeLimit;
        }
    }

    public class UploadConfig
    {
        /// <summary>
        /// 水印文字
        /// </summary>
        public string water_mark { get; set; }

        /// <summary>
        /// 文件命名规则
        /// </summary>
        public string PathFormat { get; set; }

        /// <summary>
        /// 上传表单域名称
        /// </summary>
        public string UploadFieldName { get; set; }

        /// <summary>
        /// 上传大小限制
        /// </summary>
        public int SizeLimit { get; set; }

        /// <summary>
        /// 上传允许的文件格式
        /// </summary>
        public string[] AllowExtensions { get; set; }

        /// <summary>
        /// 文件是否以 Base64 的形式上传
        /// </summary>
        public bool Base64 { get; set; }

        /// <summary>
        /// Base64 字符串所表示的文件名
        /// </summary>
        public string Base64Filename { get; set; }

        /// <summary>
        /// 动态上传目录
        /// </summary>
        public string uploads_dir { get; set; }
    }

    public class UploadResult
    {
        public UploadState State { get; set; }

        public string Url { get; set; }

        public string OriginFileName { get; set; }

        public string ErrorMessage { get; set; }
    }

    public enum UploadState
    {
        Unknown = 1,
        Success = 0,
        SizeLimitExceed = -1,
        TypeNotAllow = -2,
        FileAccessError = -3,
        NetworkError = -4,

        /// <summary>
        /// 未通过身份验证
        /// </summary>
        NotAuthenticated = -5,
    }
}